package controller

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"log"
	"net/http"
	"time"
	"ylb/config"
	"ylb/entity"
	"ylb/interceptor"
	"ylb/service"
	"ylb/service/impl"
	"ylb/tool"
	"ylb/vo"
)

type UserController struct {
	userRelevance service.UserRelevanceService
	userService   service.UserService
}

func NewUserController(gin *gin.Engine) UserController {
	controller := UserController{}
	controller.userService = impl.NewUserServiceImpl()
	controller.userRelevance = impl.NewUserRelevanceServiceImpl()
	controller.UserRoute(gin)
	return controller
}
func (userController *UserController) UserRoute(ginServer *gin.Engine) {
	group := ginServer.Group("/user")

	//context里加入session
	group.Use(interceptor.Session("topgoer"))
	{
		group.GET("/captcha", func(c *gin.Context) {
			tool.Captcha(c, 4)
		})
		group.GET("/check/:userName", userController.checkUserName)
		group.GET("/info", interceptor.TokenInterceptor(), userController.getUserInfo)
		group.POST("/login", interceptor.LimitLogin(), userController.login)
		group.POST("/update", interceptor.TokenInterceptor(), userController.updateUserInfo)
		group.POST("/update/pwd", interceptor.TokenInterceptor(), userController.updatePwd)
		group.POST("/register", userController.registerUser)
		group.POST("/forget", interceptor.TokenInterceptor(), userController.forgetUserPwd)

	}

}

func (userController *UserController) login(ctx *gin.Context) {
	userService := userController.userService
	get, exists := ctx.Get("userVo")

	loginVo := get.(vo.UserLoginVo)

	if !exists {
		ctx.JSON(200, tool.Error("传入参数有误", nil))
		return
	}

	//检查验证码
	value := loginVo.Validate

	//如果验证码错误
	if !tool.CaptchaVerify(ctx, value) {
		ctx.JSON(http.StatusOK, tool.Response(config.VALIDATE_ERROR_CODE, "验证码错误", nil))
		return
	}

	//登录服务
	user, right, msg, code := userService.Login(loginVo.LoginVoParseUser())

	if right {
		//登录成功

		//生成token
		token, _ := tool.GetToken(map[string]interface{}{
			"userName": user.UserName,
			"userId":   user.ID,
		}, time.Hour*24*3)

		//响应数据
		log.Println("---- user login :", user.UserName+"   登录成功!")
		ctx.JSON(http.StatusOK, tool.Success("登录成功", gin.H{
			"token": token,
		}))
		ctx.Set("loginCode", config.LOGIN_SUCCESS_CODE)
	} else {
		//登录失败
		ctx.Set("loginCode", config.LOGIN_FAILED_CODE)
		ctx.JSON(http.StatusOK, tool.Response(code, msg, nil))
	}

}
func (userController *UserController) getUserInfo(ctx *gin.Context) {

	id := GetUserId(ctx)

	userInfo := userController.userService.GetUserInfoByUserId(id)
	//不能直接输出user对象，转换成vo.UserInfoVo对象
	ctx.JSON(http.StatusOK, tool.Success("ok bro", gin.H{
		"userInfo": userInfo,
	}))

}

func (userController *UserController) updateUserInfo(context *gin.Context) {
	id := GetUserId(context)

	var uuv entity.User

	err := context.BindJSON(&uuv)
	uuv.ID = id
	if err != nil {

		context.JSON(200, tool.Error("传入参数有误", nil))
		return

	}
	fmt.Printf("%v\n", uuv)
	update := userController.userService.Update(uuv)
	if update == 0 {
		context.JSON(http.StatusOK, tool.Error("失败", gin.H{}))
	} else {
		context.JSON(http.StatusOK, tool.Success("成功", gin.H{}))
	}
	//context.JSON(http.StatusOK, tool.Success("成功", gin.H{}))
}

func (userController *UserController) registerUser(context *gin.Context) {
	var user vo.UserRegisterVo
	err := context.BindJSON(&user)

	if err != nil {

		context.JSON(200, tool.Error("传入参数有误", nil))
		return

	}

	//取出session的emailCode比对
	code, redisGetErr := service.GetEmailRegisterCode(user.Email)

	if redisGetErr != nil {
		context.JSON(http.StatusOK, tool.Error("验证码不存在", gin.H{}))
		return
	}

	if user.Validate != code {
		context.JSON(http.StatusOK, tool.Error("验证码错误", gin.H{}))
		return
	}
	//UserRegisterVo对象转换成user对象
	parseUser := user.RegisterVoParseUser()

	//新增用户
	row := userController.userService.InsertUser(&parseUser)
	if row == 0 {

		context.JSON(http.StatusOK, tool.Error("失败", gin.H{}))
	} else {

		//TODO 绑定邮箱服务
		userController.userRelevance.BindEmail(parseUser.ID, user.Email)

		context.JSON(http.StatusOK, tool.Success("成功", gin.H{}))
	}

}

func (userController *UserController) forgetUserPwd(context *gin.Context) {

}

func (userController *UserController) checkUserName(context *gin.Context) {
	param := context.Param("userName")
	user := userController.userService.SelectUserInfoByUserName(param)
	if user.UserName == "" {
		context.JSON(http.StatusOK, tool.Error("不存在", gin.H{}))
	} else {
		context.JSON(http.StatusOK, tool.Success("存在", gin.H{}))
	}
}
func (userController UserController) updatePwd(ctx *gin.Context) {
	id := GetUserId(ctx)
	m := map[string]string{}
	err := ctx.Bind(&m)

	pwd := m["password"]
	if err != nil || pwd == "" {
		ctx.JSON(http.StatusOK, tool.Error("参数有误", gin.H{}))
		return
	}
	update := userController.userService.Update(entity.User{
		Model: gorm.Model{
			ID: id,
		},
		Password: pwd,
	})
	if update == 0 {
		ctx.JSON(http.StatusOK, tool.Error("修改失败", gin.H{}))
	} else {
		ctx.JSON(http.StatusOK, tool.Success("修改成功", gin.H{}))
	}
}
